package cn.chiship.framework.business.biz.product.service.impl;

import cn.chiship.framework.business.biz.product.entity.ProductBrand;
import cn.chiship.framework.business.biz.product.entity.ProductBrandExample;
import cn.chiship.framework.business.biz.product.mapper.ProductBrandMapper;
import cn.chiship.framework.common.constants.CommonCacheConstants;
import cn.chiship.framework.common.util.FrameworkUtil2;
import cn.chiship.sdk.cache.service.RedisService;
import cn.chiship.sdk.core.base.BaseResult;
import cn.chiship.sdk.core.base.constants.BaseConstants;
import cn.chiship.sdk.core.util.ObjectUtil;
import cn.chiship.sdk.core.util.StringUtil;
import cn.chiship.sdk.framework.base.BaseServiceImpl;
import cn.chiship.framework.business.biz.product.mapper.ProductCategoryMapper;
import cn.chiship.framework.business.biz.product.entity.ProductCategory;
import cn.chiship.framework.business.biz.product.entity.ProductCategoryExample;
import cn.chiship.framework.business.biz.product.service.ProductCategoryService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 商品分类业务接口实现层
 * 2024/12/11
 *
 * @author lijian
 */
@Service
public class ProductCategoryServiceImpl extends BaseServiceImpl<ProductCategory, ProductCategoryExample> implements ProductCategoryService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ProductCategoryServiceImpl.class);

    @Resource
    ProductCategoryMapper productCategoryMapper;
    @Resource
    ProductBrandMapper productBrandMapper;
    @Resource
    RedisService redisService;

    @Override
    public BaseResult treeTable(ProductCategoryExample productCategoryExample) {
        cacheProductCategory();
        List<ProductCategory> productCategories = productCategoryMapper.selectByExample(productCategoryExample);
        return BaseResult.ok(assemblyProductCategoryTree("0", productCategories));
    }

    @Override
    public BaseResult cacheTreeTable(String pid) {
        if (StringUtil.isNullOrEmpty(pid)) {
            pid = "0";
        }
        String idKey = CommonCacheConstants.buildKey(CommonCacheConstants.REDIS_PRODUCT_CATEGORY_PREFIX) + ":id";

        Map<Object, Object> maps = redisService.hget(idKey);
        List<ProductCategory> productCategories = new ArrayList<>();
        for (Map.Entry<Object, Object> entry : maps.entrySet()) {
            ProductCategory productCategory = (ProductCategory) entry.getValue();
            if (Byte.valueOf("1").equals(productCategory.getIsShow())) {
                productCategories.add(productCategory);
            }
        }
        productCategories.sort((o1, o2) -> o2.getOrders().compareTo(o1.getOrders()));
        return BaseResult.ok(assemblyProductCategoryTree(pid, productCategories));
    }

    private List<JSONObject> assemblyProductCategoryTree(String pid, List<ProductCategory> productCategories) {
        List<JSONObject> treeVos = new ArrayList<>();
        for (ProductCategory productCategory : productCategories) {
            if (pid.equals(productCategory.getParentId())) {
                treeVos.add(JSON.parseObject(JSON.toJSONString(productCategory)));
            }
        }
        for (int i = 0; i < treeVos.size(); i++) {
            List<JSONObject> children = assemblyProductCategoryTree(treeVos.get(i).getString("id"), productCategories);
            if (!children.isEmpty()) {
                treeVos.get(i).put("children", children);
            }
        }
        return treeVos;
    }

    @Override
    public JSONObject assembleData(ProductCategory productCategory) {
        if (productCategory == null) {
            return new JSONObject();
        }
        JSONObject json = JSON.parseObject(JSON.toJSONString(productCategory));
        json.putAll(getParentInfoByTreeNumber(productCategory.getTreeNumber()));
        return json;
    }

    @Override
    public BaseResult generateTreeNumber(String pid) {
        String treeNumber = FrameworkUtil2.generateTreeNumber(productCategoryMapper.getTreeNumberByPid(pid));
        if (StringUtil.isNullOrEmpty(treeNumber)) {
            return BaseResult.error("生成层级出错？");
        }
        return BaseResult.ok(treeNumber);
    }

    @Override
    public BaseResult insertSelective(ProductCategory productCategory) {
        ProductCategoryExample productCategoryExample = new ProductCategoryExample();
        productCategoryExample.createCriteria()
                .andParentIdEqualTo(productCategory.getParentId())
                .andCategoryNameEqualTo(productCategory.getCategoryName());
        if (!productCategoryMapper.selectByExample(productCategoryExample).isEmpty()) {
            return BaseResult.error("分类名称已存在，请重新输入！");
        }
        BaseResult baseResult = generateTreeNumber(productCategory.getParentId());
        if (!baseResult.isSuccess()) {
            return baseResult;
        }
        productCategory.setTreeNumber(baseResult.getData().toString());
        productCategory.setLevel(productCategory.getTreeNumber().split("-").length);
        return super.insertSelective(productCategory);
    }

    @Override
    public BaseResult updateByPrimaryKeySelective(ProductCategory productCategory) {
        ProductCategoryExample productCategoryExample = new ProductCategoryExample();
        productCategoryExample.createCriteria()
                .andParentIdEqualTo(productCategory.getParentId())
                .andCategoryNameEqualTo(productCategory.getCategoryName())
                .andIdNotEqualTo(productCategory.getId());
        if (!productCategoryMapper.selectByExample(productCategoryExample).isEmpty()) {
            return BaseResult.error("分类名称已存在，请重新输入！");
        }
        return super.updateByPrimaryKeySelective(productCategory);
    }

    @Override
    public void cacheProductCategory() {
        String idKey = CommonCacheConstants.buildKey(CommonCacheConstants.REDIS_PRODUCT_CATEGORY_PREFIX) + ":id";
        String treeKey = CommonCacheConstants.buildKey(CommonCacheConstants.REDIS_PRODUCT_CATEGORY_PREFIX) + ":tree";

        redisService.del(treeKey);
        redisService.del(idKey);
        ProductCategoryExample productCategoryExample = new ProductCategoryExample();
        productCategoryExample.createCriteria().andIsDeletedEqualTo(BaseConstants.NO);
        List<ProductCategory> productCategories = productCategoryMapper.selectByExample(productCategoryExample);
        productCategories.forEach(productCategory -> {
            redisService.hset(idKey, productCategory.getId(), productCategory);
            if (!StringUtil.isNullOrEmpty(productCategory.getTreeNumber())) {
                redisService.hset(treeKey, productCategory.getTreeNumber(), productCategory);
            }

        });
    }

    @Override
    public String cacheGetTreeNumberById(String id) {
        String idKey = CommonCacheConstants.buildKey(CommonCacheConstants.REDIS_PRODUCT_CATEGORY_PREFIX) + ":id";

        ProductCategory productCategory = (ProductCategory) redisService.hget(idKey, id);
        if (ObjectUtil.isEmpty(productCategory)) {
            return null;
        }
        return productCategory.getTreeNumber();
    }

    @Override
    public JSONObject getParentInfoById(String id) {
        return getParentInfoByTreeNumber(cacheGetTreeNumberById(id));
    }

    @Override
    public JSONObject getParentInfoByTreeNumber(String treeNumber) {
        JSONObject json = new JSONObject();

        String treeKey = CommonCacheConstants.buildKey(CommonCacheConstants.REDIS_PRODUCT_CATEGORY_PREFIX) + ":tree";

        if (StringUtil.isNullOrEmpty(treeNumber)) {
            return json;
        }
        List<String> treeNumbers = FrameworkUtil2.getAllParentTreeNumber(treeNumber);
        List<String> ids = new ArrayList<>();
        List<String> names = new ArrayList<>();
        for (String tree : treeNumbers) {
            ProductCategory productCategory = (ProductCategory) redisService.hget(treeKey, tree);
            if (ObjectUtil.isNotEmpty(productCategory)) {
                ids.add(productCategory.getId());
                names.add(productCategory.getCategoryName());
            }

        }
        json.put("_fullCategoryIds", ids);
        json.put("_fullCategoryNames", names);
        json.put("_fullCategoryId", StringUtil.join(ids, ","));
        json.put("_fullCategoryName", StringUtil.join(names, ">"));
        return json;
    }

    @Override
    public String getCategoryNameById(String id, Boolean isFull) {
        JSONObject json = getParentInfoById(id);
        if (Boolean.TRUE.equals(isFull)) {
            return json.getString("_fullCategoryName");
        }
        List<String> categoryNames = json.getObject("_fullCategoryNames", List.class);
        return categoryNames.get(categoryNames.size() - 1);
    }

    @Override
    public BaseResult bindBrand(String id, List<String> brandIds) {
        ProductCategory productCategory = productCategoryMapper.selectByPrimaryKey(id);
        if (brandIds.isEmpty()) {
            return BaseResult.error("至少选择一个要关联的品牌");
        }
        productCategory.setBrandIds(StringUtil.join(brandIds, ","));
        return super.updateByPrimaryKeySelective(productCategory);
    }

    @Override
    public BaseResult listBindBrand(String id) {
        List<ProductBrand> productBrands = new ArrayList<>();
        ProductCategory productCategory = productCategoryMapper.selectByPrimaryKey(id);
        String bindBrandId = productCategory.getBrandIds();
        if (StringUtil.isNullOrEmpty(bindBrandId)) {
            return BaseResult.ok(productBrands);
        }
        ProductBrandExample productBrandExample = new ProductBrandExample();
        productBrandExample.createCriteria().andIdIn(StringUtil.strToListString(bindBrandId, ","));
        productBrandExample.setOrderByClause("orders desc");
        productBrands = productBrandMapper.selectByExample(productBrandExample);
        return BaseResult.ok(productBrands);
    }
}
